Popularity of programming languages

What programming languages are the most popular on GitHub?

Here we have gathered a large dataset of the most popular GitHub repositories to answer this question and many more.

We start off by visualising the popularity of programming languages according to our collected data. This is data gathered from the 100 000 most popular repositories on GitHub.

Note that not all languages are shown in this treemap, see the next graph for a list of all collected languages

Next we show the popularity of all programming languages in a new diagram.

The important thing to observe is how varied software projects are in their choice of programming language. While the same few languages dominate, there is still room for experimentation with new languages.


Popularity of language features

What languages support what features?

How popular are these features?

Here we analyze the popularity of features using the most popular programming languages.

We do this by grouping the popularity of different programming languages into the features we intend to analyze. Next we present what features we wish to analyze.

Language Features:

Type systems

  • Static
  • Dynamic

Compiled and Interpreted languages

  • Scripting
  • Native compilation
  • Byte code compilation

Supported Paradigms

  • Functional
  • Procedural
  • Object Oriented
  • Multi-paradigm

If a language supports multiple paradigms we give it the feature of “Multi-paradigm”

Size is proportional to popularity


Next we compare the popularity of these language features.

Note that we have categorized for example JavaScript and TypeScript as functional languages. Though these are not considered pure functional languages they implement many of the features of a functional programming language and considering that no pure functional programming languages made it into the top ten it does not make it very interesting to analyze.


What is interesting to note is while purely procedural languages are largely considered as a limiting paradigm, it is still supported by every language in the top 10. While more modern languages are usually multi paradigm it seems very unpopular to not support procedural programming.


Prediction of future popularity of languages

How will the popularity of programming languages change in the future.

Here we compare language trends and make predictions about their popularity into the future.

Note that the prediction is layered on top of the actual data so we can see how well our model matches the collected data.

The top ten languages are shown by default, click on languages in the sidebar to view more or less data.

There are many interesting observations to be made here. For example, TypeScript overtaking JavaScript, C# overtaking Java. The “pure” functional programming languages seem to have a stable popularity except for Clojure and Haskell which appear to be in a downward trend.

Distribution of bugs in each language

Is there any correlation between the amount of bugs in a repository and the choice of programming language used in that repository?

Here we intend to analyze this relation to see if there is any correlation, and if so what languages are most associated with bugs.

Each dot represents a repository and it’s position in the chart represents that repositories average percentage of reported bugs.

The percentage is based on GitHub issues and pull requests meaning that any issue or pull request labeled as a bug or bug fix would contribute to the bug percentage.

Hover over a dot to see what repository it represents.


We can already see that there are slight differences in the distribution of bugs in the languages.

Now we will aggregate the data into mean and median bug percentage for each language.

This table shows the mean and median percentage of bugs for all repositories using a particular programming language.

The table is sorted by the languages that have the most bugs.


Language Mean Bug % Median Bug % Occurrences of Language
15 PowerShell 14.486648 12.500000 315
2 C# 13.921641 11.122598 562
22 TypeScript 13.730277 10.434586 644
18 Rust 13.666125 11.007843 612
12 Kotlin 13.386051 10.383332 460
8 Go 13.121750 9.539474 631
4 Clojure 12.475246 10.169491 335
3 C++ 11.707076 7.436570 537
6 Dart 11.694106 8.163401 358
16 Python 11.591716 8.791209 555
5 CoffeeScript 11.061051 8.333333 291
7 Elixir 10.886311 8.695652 375
9 Haskell 10.715992 8.203125 363
19 Scala 10.285034 7.802548 413
21 Swift 10.070342 7.028754 453
1 C 10.026046 6.415207 450
14 PHP 9.860882 6.389776 529
11 JavaScript 9.357928 6.448013 650
10 Java 9.186963 6.060606 489
20 Shell 9.154558 5.277819 396
17 Ruby 9.133840 6.003160 497
13 Objective-C 8.443087 5.882353 352

Visualising this data into a bar chart reveals the relation of bugs between the languages.


Here we can see the languages that according to our data is likely to produce the most bugs. These results may seem unexpected, a scripting language (PowerShell) being first on the list is not very surprising, but C# and TypeScript being so high on the list is very surprising. This might hint to a shift in culture of the reporting of bugs in newer languages. Perhaps users of newer languages are more likely to use GitHub issues to report bugs. This could however also be explained by newer languages not being as mature and developed leading to more bugs. Conventions may not be fully developed yet which could lead to larger projects written in newer languages to suffer.

LS0tCnRpdGxlOiAiUHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzIG9uIEdpdEh1YiwgYnVncyBhbmQgcG9wdWxhcml0eTogQW4gZXhwbG9yYXRvcnkgZGF0YSBqb3VybmV5IgpvdXRwdXQ6ICJodG1sX25vdGVib29rIgpmaWdfd2lkdGg6IDE2MApmaWdfaGVpZ2h0OiA5MApvdXRfd2lkdGg6IDIwMCUKb3V0X2hlaWdodDogMjAwJQotLS0KCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0KaHRtbCB7CiAgICBtYXJnaW46IGF1dG87CiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgICBtYXgtd2lkdGg6IDgwdnc7CiAgICBkaXNwbGF5OiBmbGV4OwogICAgYWxpZ24taXRlbXM6IGNlbnRlcjsKICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOwp9Cgpib2R5IHsKICAgIGZvbnQtc2l6ZTogMjJweDsKICAgIG1heC13aWR0aDogODB2dzsKfQoKaW1nIHsKICAgIG1heC13aWR0aDogZml0LWNvbnRlbnQ7Cn0KCi5tYWluLWNvbnRhaW5lciB7CiAgICBhbGlnbi1pdGVtczogY2VudGVyOwogICAgZGlzcGxheTogYmxvY2s7CiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsKfQoKLmJ0bi1ncm91cCB7CiAgICBkaXNwbGF5OiBub25lOwp9CgpwIHsKICAgIGRpc3BsYXk6IGZsZXg7CiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsKICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7Cn0KCmRpdiB7CiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsKICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7CiAgICBkaXNwbGF5OiBmbGV4OwogICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsKICAgIG1heC13aWR0aDogOTB2dzsKfQoKLmJsb2NrIHsKICAgIGJhY2tncm91bmQ6IHdoaXRlOwogICAgcGFkZGluZzogMC41ZW07CiAgICBib3JkZXI6IDJweCBzb2xpZCBibGFjazsKICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7CiAgICB0ZXh0LWFsaWduOiBsZWZ0OwogICAgZm9udC1zaXplOiAxOHB4OwogICAgbWluLXdpZHRoOiAyMjBweDsKICAgIG1pbi1oZWlnaHQ6IDIwMHB4Owp9CgouYmxvY2sgPiBoMyB7CiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KYGBgCgo8aHIvPgoKIyBQb3B1bGFyaXR5IG9mIHByb2dyYW1taW5nIGxhbmd1YWdlcwoKV2hhdCBwcm9ncmFtbWluZyBsYW5ndWFnZXMgYXJlIHRoZSBtb3N0IHBvcHVsYXIgb24gR2l0SHViPwoKSGVyZSB3ZSBoYXZlIGdhdGhlcmVkIGEgbGFyZ2UgZGF0YXNldCBvZiB0aGUgbW9zdCBwb3B1bGFyIEdpdEh1YiByZXBvc2l0b3JpZXMKdG8gYW5zd2VyIHRoaXMgcXVlc3Rpb24gYW5kIG1hbnkgbW9yZS4KCldlIHN0YXJ0IG9mZiBieSB2aXN1YWxpc2luZyB0aGUgcG9wdWxhcml0eSBvZiBwcm9ncmFtbWluZyBsYW5ndWFnZXMgYWNjb3JkaW5nCnRvIG91ciBjb2xsZWN0ZWQgZGF0YS4gVGhpcyBpcyBkYXRhIGdhdGhlcmVkIGZyb20gdGhlIDEwMCAwMDAgbW9zdCBwb3B1bGFyCnJlcG9zaXRvcmllcyBvbiBHaXRIdWIuCgoqTm90ZSB0aGF0IG5vdCBhbGwgbGFuZ3VhZ2VzIGFyZSBzaG93biBpbiB0aGlzIHRyZWVtYXAsIHNlZSB0aGUgbmV4dCBncmFwaCBmb3IgYSBsaXN0IG9mIGFsbCBjb2xsZWN0ZWQgbGFuZ3VhZ2VzKgoKIVtdKC4vVHJlZW1hcC5wbmcpCgpOZXh0IHdlIHNob3cgdGhlIHBvcHVsYXJpdHkgb2YgYWxsIHByb2dyYW1taW5nIGxhbmd1YWdlcyBpbiBhIG5ldyBkaWFncmFtLgoKVGhlIGltcG9ydGFudCB0aGluZyB0byBvYnNlcnZlIGlzIGhvdyB2YXJpZWQgc29mdHdhcmUgcHJvamVjdHMgYXJlIGluIHRoZWlyCmNob2ljZSBvZiBwcm9ncmFtbWluZyBsYW5ndWFnZS4gV2hpbGUgdGhlIHNhbWUgZmV3IGxhbmd1YWdlcyBkb21pbmF0ZSwgdGhlcmUgaXMKc3RpbGwgcm9vbSBmb3IgZXhwZXJpbWVudGF0aW9uIHdpdGggbmV3IGxhbmd1YWdlcy4KCiFbXSguL0Jhci5wbmcpCgo8aHIvPgoKIyBQb3B1bGFyaXR5IG9mIGxhbmd1YWdlIGZlYXR1cmVzCgpXaGF0IGxhbmd1YWdlcyBzdXBwb3J0IHdoYXQgZmVhdHVyZXM/CgpIb3cgcG9wdWxhciBhcmUgdGhlc2UgZmVhdHVyZXM/CgpIZXJlIHdlIGFuYWx5emUgdGhlIHBvcHVsYXJpdHkgb2YgZmVhdHVyZXMgdXNpbmcgdGhlIG1vc3QgcG9wdWxhciBwcm9ncmFtbWluZwpsYW5ndWFnZXMuCgpXZSBkbyB0aGlzIGJ5IGdyb3VwaW5nIHRoZSBwb3B1bGFyaXR5IG9mIGRpZmZlcmVudCBwcm9ncmFtbWluZyBsYW5ndWFnZXMgaW50bwp0aGUgZmVhdHVyZXMgd2UgaW50ZW5kIHRvIGFuYWx5emUuIE5leHQgd2UgcHJlc2VudCB3aGF0IGZlYXR1cmVzIHdlIHdpc2ggdG8KYW5hbHl6ZS4KCkxhbmd1YWdlIEZlYXR1cmVzOiAKCjxkaXYgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGdhcDogNDBweDsgZmxleC1kaXJlY3Rpb246IHJvdzsiPgo8ZGl2IGNsYXNzPSJibG9jayI+CiMjIyBUeXBlIHN5c3RlbXMKCi0gU3RhdGljIAotIER5bmFtaWMKPC9kaXY+Cgo8ZGl2IGNsYXNzPSJibG9jayI+CiMjIyBDb21waWxlZCBhbmQgSW50ZXJwcmV0ZWQgbGFuZ3VhZ2VzCgotIFNjcmlwdGluZwotIE5hdGl2ZSBjb21waWxhdGlvbgotIEJ5dGUgY29kZSBjb21waWxhdGlvbgo8L2Rpdj4KCjxkaXYgY2xhc3M9ImJsb2NrIj4KIyMjIFN1cHBvcnRlZCBQYXJhZGlnbXMKCi0gRnVuY3Rpb25hbAotIFByb2NlZHVyYWwKLSBPYmplY3QgT3JpZW50ZWQKLSBNdWx0aS1wYXJhZGlnbQo8L2Rpdj4KPC9kaXY+CgpJZiBhIGxhbmd1YWdlIHN1cHBvcnRzIG11bHRpcGxlIHBhcmFkaWdtcyB3ZSBnaXZlIGl0IHRoZSBmZWF0dXJlIG9mCiJNdWx0aS1wYXJhZGlnbSIKCipTaXplIGlzIHByb3BvcnRpb25hbCB0byBwb3B1bGFyaXR5KgoKYGBge3IsIGNhY2hlID0gRkFMU0UsIGVjaG8gPSBGQUxTRSwgZHBpID0gMTUwLCBmaWcud2lkdGggPSAxNiwgZmlnLmhlaWdodCA9IDksIG91dC53aWR0aCA9ICIxOTIwcHgiLCBvdXQuaGVpZ2h0ID0gIjEwODBweCJ9CmxpYnJhcnkoaWdyYXBoKQpsaWJyYXJ5KG1hZ3JpdHRyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHZpc05ldHdvcmspCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KEdHYWxseSkKbGlicmFyeShuZXR3b3JrKQpsaWJyYXJ5KHNuYSkKbGlicmFyeShpbnRlcmdyYXBoKQpsaWJyYXJ5KHRpZHlncmFwaCkKbGlicmFyeShnZ3JhcGgpCgojIExvYWQgZGF0YXNldHMgZnJvbSBjc3YgZmlsZXMKbGFuZ19yZXBvcyA8LSByZWFkLmNzdjIoImxhbmdfcmVwb3NfY2xlYW5fMTAwXzAwMF92Mi5jc3YiKQpsYW5nX2ZlYXRzIDwtIHJlYWQuY3N2MigibGFuZ3VhZ2VfZmVhdHVyZXMuY3N2IikKCiMgRmluZCBvY2N1cnJlbmNlcyBvZiBlYWNoIGxhbmd1YWdlCmxhbmdzIDwtIGxhbmdfcmVwb3MkbGFuZ3VhZ2UgJT4lIHRhYmxlKCkKCiMgQ3JlYXRlIGVkZ2VzIHRvIGJlIHVzZWQgaW4gbmV0d29yayBncmFwaCB1c2luZyBhIGNzdiAtCiMgZmlsZSBtYXBwaW5nIGxhbmd1YWdlcyB0byBmZWF0dXJlcwplZGdlcyA8LSBsYW5nX2ZlYXRzICU+JQogICAgc2VsZWN0KGZyb20gPSBsYW5ndWFnZSwgdG8gPSBmZWF0dXJlKQoKIyBHZXQgYWxsIGZlYXR1cmVzCmZlYXR1cmVzIDwtIGxhbmdfZmVhdHMkZmVhdHVyZSAlPiUgdGFibGUoKSAlPiUgbmFtZXMoKQoKIyBHZXQgb25seSBsYW5ndWFnZSBvY2N1cnJlbmNlcwpsYW5nX29jY3VycmVuY2VzIDwtIGxhbmdzICU+JSB1bmxpc3QoKSAlPiUgdW5uYW1lKCkKbmFtZXMobGFuZ19vY2N1cnJlbmNlcykgPC0gYygpCgojIENvbnN0cnVjdCBub2RlcyBmb3IgdXNlIGluIG5ldHdvcmsgZ3JhcGgKbm9kZXMgPC0gZGF0YS5mcmFtZShub2RlID0gbmFtZXMobGFuZ3MpLCBvY2N1cnJlbmNlcyA9IGxhbmdfb2NjdXJyZW5jZXMpCm5vZGVzJG9jY3VycmVuY2VzLlZhcjEgPC0gTlVMTApub2RlcyRvY2N1cnJlbmNlcyA8LSBub2RlcyRvY2N1cnJlbmNlcy5GcmVxCm5vZGVzJG9jY3VycmVuY2VzLkZyZXEgPC0gTlVMTApub2RlcyR0eXBlIDwtICJMYW5ndWFnZSIKbm9kZXMgPC0gbm9kZXNbbm9kZXMkbm9kZSAlaW4lIGVkZ2VzJGZyb20sIF0KCiMgQ29uc3RydWN0IEZlYXR1cmVzIGRhdGEgZnJhbWUgdG8gY2FsY3VsYXRlIHBvcHVsYXJpdHkgb2YgZmVhdHVyZXMKZmVhdHVyZXNfZGYgPC0gZGF0YS5mcmFtZShub2RlID0gZmVhdHVyZXMpCmZlYXR1cmVzX2RmJHR5cGUgPC0gIkZlYXR1cmUiCmZlYXR1cmVzX2RmJG9jY3VycmVuY2VzIDwtIDAKCiMgQ2FsY3VsYXRlIHBvcHVsYXJpdHkgb2YgZmVhdHVyZXMKZm9yIChpIGluIGZlYXR1cmVzX2RmJG5vZGUpIHsKICAgIGZlYXRfbGFuZ3MgPC0gZWRnZXNbZWRnZXMkdG8gPT0gaSwgXSRmcm9tCiAgICBmZWF0dXJlc19kZltmZWF0dXJlc19kZiRub2RlID09IGkgLCBdJG9jY3VycmVuY2VzIDwtIHN1bShsYW5nc1tuYW1lcyhsYW5ncykgJWluJSBmZWF0X2xhbmdzXSkKfQoKIyBBZGQgZmVhdHVyZXMgdG8gbm9kZXMKbm9kZXMgPC0gcmJpbmQobm9kZXMsIGZlYXR1cmVzX2RmKQoKIyBDb25zdHJ1Y3QgZ3JhcGggb2JqZWN0IGZyb20gZGF0YSBmcmFtZQpnX2RhdGEgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKGQgPSBlZGdlcywgdmVydGljZXMgPSBub2RlcywgZGlyZWN0ZWQgPSBUUlVFKQoKIyBTZXQgc2VlZCBmb3IgZ2VuZXJhdGluZyBncmFwaApzZXQuc2VlZCgzNTQ0NTMpCgojIFNpemUgb2Ygbm9kZXMKdi5zaXplIDwtIFYoZ19kYXRhKSRvY2N1cnJlbmNlcwoKIyBDb2xvcnMgb2YgZWRnZXMKYXJjX2NvbG9ycyA8LSByYWluYm93KDg0MDApCgojIEdlbmVyYXRlIG5ldHdvcmsgZ3JhcGgKZmVhdF9wbG90IDwtIGdfZGF0YSAlPiUKICAgIGdncmFwaChsYXlvdXQgPSAibGdsIikgKwogICAgZ2VvbV9lZGdlX2FyYyhjb2xvdXI9YXJjX2NvbG9ycywKICAgICAgICAgICAgICAgICAgbGluZWVuZCA9ICJyb3VuZCIsCiAgICAgICAgICAgICAgICAgIHN0cmVuZ3RoID0gLjUsCiAgICAgICAgICAgICAgICAgIGFscGhhID0gLjUpICsKICAgIHRoZW1lX2dyYXBoKGJhY2tncm91bmQgPSAid2hpdGUiKSArCiAgICBnZW9tX25vZGVfcG9pbnQoc2l6ZSA9IHYuc2l6ZS8xNTAwLCBhZXMoY29sb3IgPSB0eXBlKSkgKwogICAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSksIAogICAgICAgICAgICAgICByZXBlbCA9IFRSVUUsIAogICAgICAgICAgICAgICBjb2xvdXI9ImdyYXk0MCIpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQoKZmVhdF9wbG90CgpgYGAKCjxoci8+CgpOZXh0IHdlIGNvbXBhcmUgdGhlIHBvcHVsYXJpdHkgb2YgdGhlc2UgbGFuZ3VhZ2UgZmVhdHVyZXMuCgpOb3RlIHRoYXQgd2UgaGF2ZSBjYXRlZ29yaXplZCBmb3IgZXhhbXBsZSBKYXZhU2NyaXB0IGFuZCBUeXBlU2NyaXB0IGFzCmZ1bmN0aW9uYWwgbGFuZ3VhZ2VzLiBUaG91Z2ggdGhlc2UgYXJlIG5vdCBjb25zaWRlcmVkIHB1cmUgZnVuY3Rpb25hbCBsYW5ndWFnZXMKdGhleSBpbXBsZW1lbnQgbWFueSBvZiB0aGUgZmVhdHVyZXMgb2YgYSBmdW5jdGlvbmFsIHByb2dyYW1taW5nIGxhbmd1YWdlIGFuZApjb25zaWRlcmluZyB0aGF0IG5vIHB1cmUgZnVuY3Rpb25hbCBwcm9ncmFtbWluZyBsYW5ndWFnZXMgbWFkZSBpdCBpbnRvIHRoZSB0b3AKdGVuIGl0IGRvZXMgbm90IG1ha2UgaXQgdmVyeSBpbnRlcmVzdGluZyB0byBhbmFseXplLgoKPGhyLz4KCmBgYHtyLCBjYWNoZSA9IFRSVUUsIGVjaG8gPSBGQUxTRSwgZHBpID0gMTAwLCBmaWcud2lkdGggPSAxNiwgZmlnLmhlaWdodCA9IDksIG91dC53aWR0aCA9ICIxOTIwcHgiLCBvdXQuaGVpZ2h0ID0gIjEwODBweCJ9CgojIFNvcnQgZmVhdHVyZXMgYmFzZWQgb24gcG9wdWxhcml0eQpmZWF0dXJlc19kZiA8LSBmZWF0dXJlc19kZltvcmRlcihmZWF0dXJlc19kZiRvY2N1cnJlbmNlcywgZGVjcmVhc2luZyA9IFRSVUUpLCBdCmZlYXR1cmVzX2RmJG5vZGUgPC0gZmFjdG9yKGZlYXR1cmVzX2RmJG5vZGUsIGxldmVscyA9IGZlYXR1cmVzX2RmJG5vZGUpCgojIFByZXNlbnQgdGhlIGZlYXR1cmUgcG9wdWxhcml0eSBpbiBhIGJhciBjaGFydApmZWF0X2JhciA8LSBmZWF0dXJlc19kZiAlPiUgZ2dwbG90KGFlcyh4ID0gbm9kZSwgeSA9IG9jY3VycmVuY2VzLCBmaWxsID0gbm9kZSkpICsKICAgIGdlb21fY29sKCkgKwogICAgbGFicyh4ID0gIkZlYXR1cmUiLCB5ID0gIlBvcHVsYXJpdHkiKSArCiAgICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWUgPSAiRmVhdHVyZSIpCgpnZ3Bsb3RseShmZWF0X2JhcikKCmBgYAoKV2hhdCBpcyBpbnRlcmVzdGluZyB0byBub3RlIGlzIHdoaWxlIHB1cmVseSBwcm9jZWR1cmFsIGxhbmd1YWdlcyBhcmUgbGFyZ2VseQpjb25zaWRlcmVkIGFzIGEgbGltaXRpbmcgcGFyYWRpZ20sIGl0IGlzIHN0aWxsIHN1cHBvcnRlZCBieSBldmVyeSBsYW5ndWFnZSBpbgp0aGUgdG9wIDEwLiBXaGlsZSBtb3JlIG1vZGVybiBsYW5ndWFnZXMgYXJlIHVzdWFsbHkgbXVsdGkgcGFyYWRpZ20gaXQgc2VlbXMKdmVyeSB1bnBvcHVsYXIgdG8gbm90IHN1cHBvcnQgcHJvY2VkdXJhbCBwcm9ncmFtbWluZy4KCjxoci8+CgojIFByZWRpY3Rpb24gb2YgZnV0dXJlIHBvcHVsYXJpdHkgb2YgbGFuZ3VhZ2VzCgpIb3cgd2lsbCB0aGUgcG9wdWxhcml0eSBvZiBwcm9ncmFtbWluZyBsYW5ndWFnZXMgY2hhbmdlIGluIHRoZSBmdXR1cmUuCgpIZXJlIHdlIGNvbXBhcmUgbGFuZ3VhZ2UgdHJlbmRzIGFuZCBtYWtlIHByZWRpY3Rpb25zIGFib3V0IHRoZWlyIHBvcHVsYXJpdHkKaW50byB0aGUgZnV0dXJlLgoKTm90ZSB0aGF0IHRoZSBwcmVkaWN0aW9uIGlzIGxheWVyZWQgb24gdG9wIG9mIHRoZSBhY3R1YWwgZGF0YSBzbyB3ZSBjYW4gc2VlIGhvdyB3ZWxsIG91cgptb2RlbCBtYXRjaGVzIHRoZSBjb2xsZWN0ZWQgZGF0YS4KCipUaGUgdG9wIHRlbiBsYW5ndWFnZXMgYXJlIHNob3duIGJ5IGRlZmF1bHQsIGNsaWNrIG9uIGxhbmd1YWdlcyBpbiB0aGUgc2lkZWJhciB0byB2aWV3IG1vcmUgb3IgbGVzcyBkYXRhLioKCmBgYHtyLCBjYWNoZSA9IFRSVUUsIGVjaG8gPSBGQUxTRSwgZHBpID0gMTAwLCBmaWcud2lkdGggPSAxNiwgZmlnLmhlaWdodCA9IDksIG91dC53aWR0aCA9ICIxOTIwcHgiLCBvdXQuaGVpZ2h0ID0gIjEwODBweCJ9CgpsYW5nX3JlcG9zX2NsZWFuIDwtIHJlYWQuY3N2MigibGFuZ19yZXBvc19jbGVhbl8xMDBfMDAwX3YyLmNzdiIpCgpsaWJyYXJ5KG1hZ3JpdHRyKQoKIyBGb3JtYXQgZGF0ZSBzdHJpbmdzIHRvIGRhdGUgZGF0YSB0eXBlCmxhbmdfcmVwb3NfY2xlYW4kY3JlYXRlZEF0IDwtICBsYW5nX3JlcG9zX2NsZWFuJGNyZWF0ZWRBdCAlPiUgYXMuRGF0ZShmb3JtYXQgPSAiJVktJW0tJWQiKQpsYW5nX3JlcG9zX2NsZWFuJHB1c2hlZEF0IDwtIGxhbmdfcmVwb3NfY2xlYW4kcHVzaGVkQXQgJT4lIGFzLkRhdGUoZm9ybWF0ID0gIiVZLSVtLSVkIikKCiMgRmluZCB0aGUgc3RhcnQgYW5kIGVuZCBkYXRlCm1pbiA8LSBsYW5nX3JlcG9zX2NsZWFuW3doaWNoLm1pbihsYW5nX3JlcG9zX2NsZWFuJGNyZWF0ZWRBdCksIF0kY3JlYXRlZEF0Cm1heCA8LSBsYW5nX3JlcG9zX2NsZWFuW3doaWNoLm1heChsYW5nX3JlcG9zX2NsZWFuJGNyZWF0ZWRBdCksIF0kY3JlYXRlZEF0CgojIENyZWF0ZSBzZXF1ZW5jZSB0aW1lbGluZSBzcGFubmluZyB0aW1lc3BhbgpyYW5nZSA8LSBhcy5EYXRlKHNlcShtaW4sIG1heCwgYnkgPSAiZGF5IikpCgojIEV4dHJhY3QgdGhlIGxhbmd1YWdlcyB0aGF0IG9jY3VyIGluIHRoZSBkYXRhc2V0IGFzIHVuaXF1ZSB2YWx1ZXMKbGFuZ3VhZ2VzIDwtIGxhbmdfcmVwb3NfY2xlYW4kbGFuZ3VhZ2UgJT4lIHVubGlzdCgpICU+JSB0YWJsZSgpICU+JSBuYW1lcygpCnRvcF9sYW5ndWFnZXMgPC0gbGFuZ19yZXBvc19jbGVhbiRsYW5ndWFnZSAlPiUgdW5saXN0KCkgJT4lIHRhYmxlKCkgJT4lIHNvcnQoZGVjcmVhc2luZyA9IFRSVUUpCgojIENyZWF0ZSB0aW1lbGluZSBmb3IgcHJvY2Vzc2luZyBsYW5ndWFnZSBwb3B1bGFyaXR5CmxhbmdfdGltZWxpbmUgPC0gZGF0YS5mcmFtZShkYXkgPSByYW5nZSkKCiMgQWRkIGxhbmd1YWdlcyBhcyBjb2x1bW5zIGluIHRpbWVsaW5lCmxhbmdfZGYgPC0gZGF0YS5mcmFtZShtYXRyaXgoMCwgbmNvbCA9IGxlbmd0aChsYW5ndWFnZXMpKSkKY29sbmFtZXMobGFuZ19kZikgPC0gbGFuZ3VhZ2VzCmxhbmdfdGltZWxpbmUgPC0gY2JpbmQobGFuZ190aW1lbGluZSwgbGFuZ19kZikKCiMgRm9yIGV2ZXJ5IHJlcG8gYWRkIDEgdG8gdGhlIHRpbWVzcGFuIHdoZXJlIGl0IGhhcyBiZWVuIGFjdGl2ZSBjcmVhdGVkQXQgLT4gcHVzaGVkQXQKZm9yIChpIGluIDE6bnJvdyhsYW5nX3JlcG9zX2NsZWFuKSkgewogICAgcmVwbyA8LSBsYW5nX3JlcG9zX2NsZWFuW2ksIF0KICAgIGxhbmdfdGltZWxpbmVbYXMubnVtZXJpYyhsYW5nX3RpbWVsaW5lJGRheSkgJWluJSByZXBvJGNyZWF0ZWRBdDpyZXBvJHB1c2hlZEF0LCByZXBvJGxhbmd1YWdlXSA8LQogICAgICAgIGxhbmdfdGltZWxpbmVbYXMubnVtZXJpYyhsYW5nX3RpbWVsaW5lJGRheSkgJWluJSByZXBvJGNyZWF0ZWRBdDpyZXBvJHB1c2hlZEF0LCByZXBvJGxhbmd1YWdlXSArIDEKfQoKIyBSZW1vdmUgbW9zdCByZWNlbnQgZGF0YSBhcyBpdCBpcyBpbmFjY3VyYXRlCmxhbmdfdGltZWxpbmUgPC0gbGFuZ190aW1lbGluZVtsYW5nX3RpbWVsaW5lJGRheSA8IG1heCAtIDUwMCwgXQoKIyBUdXJuIHRpbWVsaW5lIGxhbmd1YWdlIGNvbHVtbnMgaW50byB2YXJpYWJsZXMgb24gInZhcmlhYmxlIiBjb2x1bW4KbGlicmFyeShyZXNoYXBlMikKbGFuZ190aW1lX2RmIDwtIG1lbHQobGFuZ190aW1lbGluZSwgaWQudmFycyA9ICJkYXkiKQoKIyBOdW1lcmljYWwgZGF0ZSByZXByZXNlbnRhdGlvbiBmb3IgdXNlIGluIHJlZ3Jlc3Npb24gbW9kZWwKbGFuZ190aW1lX2RmJGRheV9udW0gPC0gYXMubnVtZXJpYyhsYW5nX3RpbWVfZGYkZGF5KQoKIyBSZW1vdmUgZnVydGhlciB1bnVzZWQgY29sdW1uCmxhbmdfdGltZV9kZiRkYXlfbnVtIDwtIE5VTEwKCiMgQ2hhbmdlIG5hbWUgb2YgY29sdW1uICJ2YXJpYWJsZSIKbGFuZ190aW1lX2RmJExhbmd1YWdlIDwtIGxhbmdfdGltZV9kZiR2YXJpYWJsZQpsYW5nX3RpbWVfZGYkdmFyaWFibGUgPC0gTlVMTAoKbGFuZ19vcmRlciA8LSBsYW5ncyAlPiUgc29ydChkZWNyZWFzaW5nID0gVFJVRSkgJT4lIG5hbWVzKCkKCmxhbmdfdGltZV9kZiRMYW5ndWFnZSA8LSBmYWN0b3IobGFuZ190aW1lX2RmJExhbmd1YWdlLCBsZXZlbHMgPSBsYW5nX29yZGVyKQpsYW5nX3RpbWVfZGYgPC0gbGFuZ190aW1lX2RmW29yZGVyKG1hdGNoKGxhbmdfdGltZV9kZiRMYW5ndWFnZSwgbGFuZ19vcmRlcikpLCBdCiMgVmlzdWFsaXNpbmcgY3VycmVudCBtb2RlbCBhbmQgZGF0YSB3aXRoIHRoZSBtb2RlbCBwcmVkaWN0aW9uIHVwIHRvIDIwMzAKIyBNb2RlbCBpcyBnZW5lcmF0ZWQgYWdhaW4gaW50ZXJuYWxseSBpbiBncmFwaCwKIyBidXQgdXNlcyB0aGUgc2FtZSBtb2RlbCBhbmQgZm9ybXVsYWUgYXMgInRpbWVsaW5lLmZpdCIKbGlicmFyeShnZ3Bsb3QyKQp0cmVuZF9wbG90IDwtIGdncGxvdChsYW5nX3RpbWVfZGYsIGFlcyh4ID0gZGF5LCB5ID0gdmFsdWUsIGNvbCA9IExhbmd1YWdlKSkgKwogICAgZ2VvbV9saW5lKCkgKwogICAgeGxpbShtaW4sIGFzLkRhdGUoIjIwMzAtMDEtMDEiKSkgKwogICAgeWxpbSgwLCAxNDAwMCkgKwogICAgeGxhYigiRGF0ZSIpICsKICAgIHlsYWIoIlBvcHVsYXJpdHkiKSArCiAgICBsYWJzKGZpbGwgPSAiTGFuZ3VhZ2UiLCB0aXRsZSA9ICJGdXR1cmUgdHJlbmRzIG9mIHRoZSB0b3AgMTAgcHJvZ3JhbW1pbmcgTGFuZ3VhZ2VzIikgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbWF4IC0gNTAwKSArCiAgICBzdGF0X3Ntb290aCgKICAgICAgICBhZXMoeCA9IGRheSwgeSA9IHZhbHVlLCBjb2wgPSBMYW5ndWFnZSwgbGluZXR5cGUgPSBMYW5ndWFnZSksCiAgICAgICAgbWV0aG9kID0gImdhbSIsIGZvcm11bGEgPSB5IH4gcyh4LCBicyA9ICJjcyIpLAogICAgICAgIGZ1bGxyYW5nZSA9IFRSVUUpICsKICAgIHRoZW1lX2J3KCkKCmxpYnJhcnkocGxvdGx5KQp0cmVuZF9wbG90IDwtIGdncGxvdGx5KHRyZW5kX3Bsb3QpCnAubGVuZ3RoIDwtIGxhbmdfdGltZV9kZiRMYW5ndWFnZSAlPiUgdGFibGUoKSAlPiUgbGVuZ3RoKCkqMgoKIyBEaXNhYmxlIGV2ZXJ5dGhpbmcgZXhjZXB0IHRoZSB0b3AgMTAgbGFuZ3VhZ2VzCnRyZW5kX3Bsb3QgPC0gc3R5bGUodHJlbmRfcGxvdCwgdmlzaWJsZSA9ICJsZWdlbmRvbmx5IiwgdHJhY2VzID0gYygxMDoocC5sZW5ndGgvMiksIChwLmxlbmd0aC8yKzEwKToocC5sZW5ndGgrMSkpKQp0cmVuZF9wbG90CgpgYGAKClRoZXJlIGFyZSBtYW55IGludGVyZXN0aW5nIG9ic2VydmF0aW9ucyB0byBiZSBtYWRlIGhlcmUuIEZvciBleGFtcGxlLApUeXBlU2NyaXB0IG92ZXJ0YWtpbmcgSmF2YVNjcmlwdCwgQyMgb3ZlcnRha2luZyBKYXZhLiBUaGUgInB1cmUiIGZ1bmN0aW9uYWwKcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzIHNlZW0gdG8gaGF2ZSBhIHN0YWJsZSBwb3B1bGFyaXR5IGV4Y2VwdCBmb3IgQ2xvanVyZSBhbmQKSGFza2VsbCB3aGljaCBhcHBlYXIgdG8gYmUgaW4gYSBkb3dud2FyZCB0cmVuZC4KCiMgRGlzdHJpYnV0aW9uIG9mIGJ1Z3MgaW4gZWFjaCBsYW5ndWFnZQoKSXMgdGhlcmUgYW55IGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIGFtb3VudCBvZiBidWdzIGluIGEgcmVwb3NpdG9yeSBhbmQgdGhlCmNob2ljZSBvZiBwcm9ncmFtbWluZyBsYW5ndWFnZSB1c2VkIGluIHRoYXQgcmVwb3NpdG9yeT8KCkhlcmUgd2UgaW50ZW5kIHRvIGFuYWx5emUgdGhpcyByZWxhdGlvbiB0byBzZWUgaWYgdGhlcmUgaXMgYW55IGNvcnJlbGF0aW9uLCBhbmQKaWYgc28gd2hhdCBsYW5ndWFnZXMgYXJlIG1vc3QgYXNzb2NpYXRlZCB3aXRoIGJ1Z3MuCgpFYWNoIGRvdCByZXByZXNlbnRzIGEgcmVwb3NpdG9yeSBhbmQgaXQncyBwb3NpdGlvbiBpbiB0aGUgY2hhcnQgcmVwcmVzZW50cyB0aGF0CnJlcG9zaXRvcmllcyBhdmVyYWdlIHBlcmNlbnRhZ2Ugb2YgcmVwb3J0ZWQgYnVncy4KClRoZSBwZXJjZW50YWdlIGlzIGJhc2VkIG9uIEdpdEh1YiBpc3N1ZXMgYW5kIHB1bGwgcmVxdWVzdHMgbWVhbmluZyB0aGF0IGFueQppc3N1ZSBvciBwdWxsIHJlcXVlc3QgbGFiZWxlZCBhcyBhIGJ1ZyBvciBidWcgZml4IHdvdWxkIGNvbnRyaWJ1dGUgdG8gdGhlIGJ1ZwpwZXJjZW50YWdlLgoKKkhvdmVyIG92ZXIgYSBkb3QgdG8gc2VlIHdoYXQgcmVwb3NpdG9yeSBpdCByZXByZXNlbnRzLioKCmBgYHtyLCBjYWNoZSA9IFRSVUUsIGVjaG8gPSBGQUxTRSwgZHBpID0gMTAwLCBmaWcud2lkdGggPSAxNiwgZmlnLmhlaWdodCA9IDksIG91dC53aWR0aCA9ICIxOTIwcHgiLCBvdXQuaGVpZ2h0ID0gIjEwODBweCJ9CnJlcG9zIDwtIHJlYWQuY3N2MigiYnVnX3JlcG9zLmNzdiIpCgojIEFkZCBidWcgaXNzdWVzIHBlcmNlbnQgYW5kIGJ1ZyBwdWxsIHJlcXVlc3QgcGVyY2VudCBhcyBjb2x1bW5zIG9uIGV2ZXJ5IHJlcG8KcmVwb3MkYnVnX2lzc3Vlc19wZXJjIDwtIHJlcG9zJGJ1Z19pc3N1ZXMgLyByZXBvcyRpc3N1ZXMgKiAxMDAKcmVwb3MkYnVnX3B1bGxfcmVxdWVzdHNfcGVyYyA8LSByZXBvcyRidWdfcHVsbF9yZXF1ZXN0cyAvIHJlcG9zJHB1bGxfcmVxdWVzdHMgKiAxMDAKCiMgUmVtb3ZlIGRhdGEgd2l0aCBtYWxmb3JtZWQgcmVsYXRpb25zaGlwIGJldHdlZW4gaXNzdWVzIGFuZCBidWcgaXNzdWVzCnJlcG9zIDwtIHJlcG9zW3JlcG9zJGJ1Z19pc3N1ZXNfcGVyYyAhPSBJbmYsIF0KcmVwb3MgPC0gcmVwb3NbIWlzLm5hKHJlcG9zJGJ1Z19pc3N1ZXNfcGVyYyksIF0KcmVwb3MgPC0gcmVwb3NbcmVwb3MkYnVnX2lzc3Vlc19wZXJjICE9IDAsIF0KCiMgUmVtb3ZlIG91dGxpZXJzCnJlbW92ZV9vdXRsaWVyc19mcm9tX2RhdGFfZnJhbWUgPC0gZnVuY3Rpb24oZGF0YV9mcmFtZSwgeCkgewogICAgUSA8LSBxdWFudGlsZSh4LCBwcm9icyA9IGMoLjI1LCAuNzUpLCBuYS5ybSA9IEZBTFNFKQogICAgaXFyIDwtIElRUih4KQogICAgcmV0dXJuKHN1YnNldChkYXRhX2ZyYW1lLCB4ID4gKFFbMV0gLSAxLjUgKiBpcXIpICYgeCA8IChRWzJdICsgMS41ICogaXFyKSkpCn0KcmVwb3MgPC0gcmVtb3ZlX291dGxpZXJzX2Zyb21fZGF0YV9mcmFtZShyZXBvcywgcmVwb3MkYnVnX2lzc3Vlc19wZXJjKQoKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeSh0aWR5dmVyc2UpCmxhbmdzX29jY3VyIDwtIHRhYmxlKHJlcG9zJGxhbmd1YWdlKSAjIE9jY3VycmVuY2VzIG9mIGxhbmd1YWdlcyBpbiByZXBvcwoKIyBDYWxjdWxhdGUgbWVhbiBvZiBtZWFuIG9mIHJlcG8gYnVncyBpbiByZXBvcwpsYW5nX2J1Z3NfYXZnIDwtIHJlcG9zICU+JQogICAgZ3JvdXBfYnkobGFuZ3VhZ2UpICU+JQogICAgICAgIHN1bW1hcmlzZShzdW1fYnVncyA9IG1lYW4oYnVnX2lzc3Vlc19wZXJjKSkKbGFuZ19idWdzX2F2ZyA8LSBhcy5kYXRhLmZyYW1lKGxhbmdfYnVnc19hdmcpCgojIENhbGN1bGF0ZSBtZWFuIG9mIG1lZGlhbiBvZiByZXBvIGJ1Z3MgaW4gcmVwb3MKbGFuZ19idWdzX21lZGlhbiA8LSByZXBvcyAlPiUKICAgIGdyb3VwX2J5KGxhbmd1YWdlKSAlPiUKICAgICAgc3VtbWFyaXNlKHN1bV9idWdzID0gbWVkaWFuKGJ1Z19pc3N1ZXNfcGVyYykpCmxhbmdfYnVnc19tZWRpYW4gPC0gYXMuZGF0YS5mcmFtZShsYW5nX2J1Z3NfbWVkaWFuKQoKIyBDb25zdHJ1Y3QgZGF0YSBmcmFtZSBmb3Igdmlld2luZyBkaWZmZXJlbmNlIGluIGF2ZXJhZ2VzCmxhbmdfYnVncyA8LSBkYXRhLmZyYW1lKGxhbmcgPSBsYW5nX2J1Z3NfYXZnJGxhbmd1YWdlLCBtZWFuID0gbGFuZ19idWdzX2F2ZyRzdW1fYnVncywgbWVkaWFuID0gbGFuZ19idWdzX21lZGlhbiRzdW1fYnVncykKbGFuZ19idWdzJG9jY3VyIDwtIGxhbmdzX29jY3VyCmxhbmdfYnVncyA8LSBsYW5nX2J1Z3Nbb3JkZXIobGFuZ19idWdzJG1lYW4sIGxhbmdfYnVncyRtZWRpYW4sIGRlY3JlYXNpbmcgPSBUUlVFKSwgXQoKCiMgR2V0IHRoZSBudW1iZXIgb2YgdW5pcXVlIGxhbmd1YWdlcyBpbiB0aGUgZGF0YXNldApuX2xhbmd1YWdlcyA8LSBsZW5ndGgobGFuZ3MpCgojIEdlbmVyYXRlIGEgZGFya2VyIHJhaW5ib3cgY29sb3IgcGFsZXR0ZSBmb3IgdGhlIGRvdHMKZG90X2NvbG9ycyA8LSBoY2woc2VxKDE1LCAzNzUsIGxlbmd0aC5vdXQgPSBuX2xhbmd1YWdlcyArIDEpLCAxMDAsIDMwKQoKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdnYmVlc3dhcm0pCmxpYnJhcnkoZ2dmb3JjZSkKCiMgVmlvbGluIGNoYXJ0CmJ1Z3NfdmlvbCA8LSBnZ3Bsb3QocmVwb3MsIGFlcyh4ID0gbGFuZ3VhZ2UsIHkgPSBidWdfaXNzdWVzX3BlcmMsIHRleHQgPSBuYW1lLCBncm91cCA9IGxhbmd1YWdlKSkgKwogICAgZ2VvbV92aW9saW4oZmlsbCA9ICJ3aGl0ZSIpICsKICAgIGdlb21fc2luYShhZXMoY29sb3IgPSBsYW5ndWFnZSkpICsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBkb3RfY29sb3JzKSArCiAgICBsYWJzKHggPSAiTGFuZ3VhZ2UiLCB5ID0gIlBlcmNlbnRhZ2Ugb2YgaXNzdWVzIHRoYXQgYXJlIGJ1Z3MiKSArCiAgICB0aGVtZV9idygpICsKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpCgpidWdzX3Zpb2wgPC0gZ2dwbG90bHkoYnVnc192aW9sKQpidWdzX3Zpb2wKCmBgYAoKPGhyLz4KCldlIGNhbiBhbHJlYWR5IHNlZSB0aGF0IHRoZXJlIGFyZSBzbGlnaHQgZGlmZmVyZW5jZXMgaW4gdGhlIGRpc3RyaWJ1dGlvbiBvZiBidWdzIGluIHRoZSBsYW5ndWFnZXMuCgpOb3cgd2Ugd2lsbCBhZ2dyZWdhdGUgdGhlIGRhdGEgaW50byBtZWFuIGFuZCBtZWRpYW4gYnVnIHBlcmNlbnRhZ2UgZm9yIGVhY2ggbGFuZ3VhZ2UuCgpUaGlzIHRhYmxlIHNob3dzIHRoZSBtZWFuIGFuZCBtZWRpYW4gcGVyY2VudGFnZSBvZiBidWdzIGZvciBhbGwgcmVwb3NpdG9yaWVzCnVzaW5nIGEgcGFydGljdWxhciBwcm9ncmFtbWluZyBsYW5ndWFnZS4KCipUaGUgdGFibGUgaXMgc29ydGVkIGJ5IHRoZSBsYW5ndWFnZXMgdGhhdCBoYXZlIHRoZSBtb3N0IGJ1Z3MuKgoKPGhyLz4KCmBgYHtyLCBjYWNoZSA9IFRSVUUsIGVjaG8gPSBGQUxTRSwgZHBpID0gMTAwLCBmaWcud2lkdGggPSAxNiwgZmlnLmhlaWdodCA9IDksIG91dC53aWR0aCA9ICIxOTIwcHgiLCBvdXQuaGVpZ2h0ID0gIjEwODBweCJ9CmtuaXRyOjprYWJsZShsYW5nX2J1Z3MsIGNvbC5uYW1lcyA9IGMoIkxhbmd1YWdlIiwgIk1lYW4gQnVnICUiLCAiTWVkaWFuIEJ1ZyAlIiwgIk9jY3VycmVuY2VzIG9mIExhbmd1YWdlIikpCmBgYAoKPGhyLz4KClZpc3VhbGlzaW5nIHRoaXMgZGF0YSBpbnRvIGEgYmFyIGNoYXJ0IHJldmVhbHMgdGhlIHJlbGF0aW9uIG9mIGJ1Z3MgYmV0d2VlbiB0aGUgbGFuZ3VhZ2VzLgoKPGhyLz4KCmBgYHtyLCBjYWNoZSA9IFRSVUUsIGVjaG8gPSBGQUxTRSwgZHBpID0gMTAwLCBmaWcud2lkdGggPSAxNiwgZmlnLmhlaWdodCA9IDksIG91dC53aWR0aCA9ICIxOTIwcHgiLCBvdXQuaGVpZ2h0ID0gIjEwODBweCJ9CgpsYW5nX2J1Z3MkbGFuZyA8LSBmYWN0b3IobGFuZ19idWdzJGxhbmcsIGxldmVscyA9IGxhbmdfYnVncyRsYW5nKQoKIyBCYXIgY2hhcnQKYnVnc19iYXIgPC0gZ2dwbG90KGxhbmdfYnVncywgYWVzKHggPSBsYW5nLCB5ID0gbWVhbiwgZmlsbCA9IGxhbmcpKSArCiAgICBnZW9tX2NvbCgpICsKICAgIGxhYnModGl0bGUgPSAiQXZlcmFnZSBCdWcgUGVyY2VudGFnZSBwZXIgTGFuZ3VhZ2UiLAogICAgICAgICB4ID0gIkxhbmd1YWdlIiwKICAgICAgICAgeSA9ICJCdWcgUGVyY2VudGFnZSIpICsKICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xKSkgKwogICAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSByZXYobGV2ZWxzKCJsYW5nIikpKSArCiAgICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWUgPSAiTGFuZ3VhZ2UiKQoKZ2dwbG90bHkoYnVnc19iYXIpCgpgYGAKCkhlcmUgd2UgY2FuIHNlZSB0aGUgbGFuZ3VhZ2VzIHRoYXQgYWNjb3JkaW5nIHRvIG91ciBkYXRhIGlzIGxpa2VseSB0byBwcm9kdWNlCnRoZSBtb3N0IGJ1Z3MuIFRoZXNlIHJlc3VsdHMgbWF5IHNlZW0gdW5leHBlY3RlZCwgYSBzY3JpcHRpbmcgbGFuZ3VhZ2UKKFBvd2VyU2hlbGwpIGJlaW5nIGZpcnN0IG9uIHRoZSBsaXN0IGlzIG5vdCB2ZXJ5IHN1cnByaXNpbmcsIGJ1dCBDIyBhbmQKVHlwZVNjcmlwdCBiZWluZyBzbyBoaWdoIG9uIHRoZSBsaXN0IGlzIHZlcnkgc3VycHJpc2luZy4gVGhpcyBtaWdodCBoaW50IHRvIGEKc2hpZnQgaW4gY3VsdHVyZSBvZiB0aGUgcmVwb3J0aW5nIG9mIGJ1Z3MgaW4gbmV3ZXIgbGFuZ3VhZ2VzLiBQZXJoYXBzIHVzZXJzIG9mCm5ld2VyIGxhbmd1YWdlcyBhcmUgbW9yZSBsaWtlbHkgdG8gdXNlIEdpdEh1YiBpc3N1ZXMgdG8gcmVwb3J0IGJ1Z3MuIFRoaXMgY291bGQKaG93ZXZlciBhbHNvIGJlIGV4cGxhaW5lZCBieSBuZXdlciBsYW5ndWFnZXMgbm90IGJlaW5nIGFzIG1hdHVyZSBhbmQgZGV2ZWxvcGVkCmxlYWRpbmcgdG8gbW9yZSBidWdzLiBDb252ZW50aW9ucyBtYXkgbm90IGJlIGZ1bGx5IGRldmVsb3BlZCB5ZXQgd2hpY2ggY291bGQKbGVhZCB0byBsYXJnZXIgcHJvamVjdHMgd3JpdHRlbiBpbiBuZXdlciBsYW5ndWFnZXMgdG8gc3VmZmVyLgo=